package com.ruoyi.dynamic.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.pojo.result.PageUtils;
import com.ruoyi.common.core.pojo.result.Pages;
import com.ruoyi.common.core.utils.CollectionUtils;
import com.ruoyi.common.core.utils.CommonUtils;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.redis.cache.CacheTemplate;
import com.ruoyi.dynamic.mapper.RoomVoteMapper;
import com.ruoyi.dynamic.model.constant.DynamicConstant;
import com.ruoyi.dynamic.model.constant.RoomChatRoomKvConstant;
import com.ruoyi.dynamic.model.pojo.entity.Gift;
import com.ruoyi.dynamic.model.pojo.entity.Room;
import com.ruoyi.dynamic.model.pojo.entity.RoomVote;
import com.ruoyi.dynamic.model.pojo.entity.RoomVoteRecord;
import com.ruoyi.dynamic.model.pojo.request.app.AppRoomHeartGetRequest;
import com.ruoyi.dynamic.model.pojo.request.app.AppRoomVoteAddRequest;
import com.ruoyi.dynamic.model.pojo.request.app.AppRoomVoteGiveRequest;
import com.ruoyi.dynamic.model.pojo.request.app.AppRoomVoteSearchRequest;
import com.ruoyi.dynamic.model.pojo.result.app.AppRoomVoteInfoResult;
import com.ruoyi.dynamic.model.pojo.result.app.AppRoomVoteResult;
import com.ruoyi.dynamic.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 房间投票 服务实现类
 * </p>
 *
 * @author Gnc
 * @since 2025-01-02
 */
@Service
public class RoomVoteServiceImpl extends ServiceImpl<RoomVoteMapper, RoomVote> implements IRoomVoteService {

    @Autowired
    private IRoomService iRoomService;
    @Autowired
    private IMessageService iMessageService;
    @Autowired
    private IGiftService iGiftService;
    @Autowired
    private IRoomVoteRecordService iRoomVoteRecordService;
    @Autowired
    private IPayService iPayService;

    @Override
    public AppRoomVoteInfoResult add(AppRoomVoteAddRequest request, Long userId) {
        Room verify = iRoomService.verify(request.getRoomId());
        Assert.isTrue(verify.getUserId().equals(userId), "只有主持才能操作");
        Gift otherGift = iGiftService.verify(request.getOtherGiftId());
        Gift theseGift = iGiftService.verify(request.getTheseGiftId());
        Assert.isTrue(request.getVoteTime() >= 60, "投票时长要不小于60s");

        Long count = lambdaQuery()
                .eq(RoomVote::getRoomId, request.getRoomId())
                .in(RoomVote::getStatus, DynamicConstant.CheckStatus.YES, DynamicConstant.CheckStatus.FENG)
                .count();
        Assert.isTrue(count == 0, "当前房间还有未结束的投票场次无法开启");

        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date());
        instance.add(Calendar.SECOND, +request.getVoteTime());

        RoomVote roomVote = new RoomVote();
        roomVote.setOtherGiftId(request.getOtherGiftId());
        roomVote.setTheseGiftId(request.getTheseGiftId());
        roomVote.setRoomId(request.getRoomId());
        roomVote.setStatus(DynamicConstant.CheckStatus.YES);
        roomVote.setCreateTime(new Date());
        roomVote.setVoteTime(request.getVoteTime());
        roomVote.setUserId(verify.getUserId());
        roomVote.setVoteOther(request.getVoteOther());
        roomVote.setVoteThese(request.getVoteThese());
        roomVote.setEndTime(instance.getTime());
        roomVote.setTheseGiftImg(theseGift.getGiftImg());
        roomVote.setOtherGiftImg(otherGift.getGiftImg());
        roomVote.setOtherGiftPrice(otherGift.getGiftPrice());
        roomVote.setTheseGiftPrice(theseGift.getGiftPrice());
        if (save(roomVote)) {
            //发送redis过期事件
            CacheTemplate.setCacheExpire(RoomChatRoomKvConstant.ROOM_VOTE + roomVote.getId(), roomVote.getId(), Long.valueOf(roomVote.getVoteTime()), TimeUnit.SECONDS);

            AppRoomVoteInfoResult build = AppRoomVoteInfoResult
                    .builder()
                    .id(roomVote.getId())
                    .otherGiftId(roomVote.getOtherGiftId())
                    .roomId(roomVote.getRoomId())
                    .status(roomVote.getStatus())
                    .theseGiftId(roomVote.getTheseGiftId())
                    .userId(roomVote.getUserId())
                    .voteOther(roomVote.getVoteOther())
                    .voteThese(roomVote.getVoteThese())
                    .voteTime(roomVote.getVoteTime())
                    .otherGiftImg(otherGift.getGiftImg())
                    .otherGiftPrice(otherGift.getGiftPrice())
                    .theseGiftImg(theseGift.getGiftImg())
                    .theseGiftPrice(theseGift.getGiftPrice())
                    .residueTime(request.getVoteTime())
                    .build();
            iMessageService.setRoomChatRoomAttr(verify.getGroupId(), verify.getUserId().toString(), RoomChatRoomKvConstant.ROOM_RANK_INFO, JSONObject.toJSONString(build), 0, "", "");


            AppRoomVoteResult result = AppRoomVoteResult.builder()
                    .leftGiftMoney(BigDecimal.ZERO)
                    .rightGiftMoney(BigDecimal.ZERO)
                    .build();
            iMessageService.setRoomChatRoomAttr(verify.getGroupId(), verify.getUserId().toString(), RoomChatRoomKvConstant.ROOM_VOTE_GIFT_INFO, JSONObject.toJSONString(result), 0, "", "");

            return build;
        }
        return null;

    }

    @Override
    public boolean over(AppRoomHeartGetRequest request, Long userId) {
        RoomVote vote = verify(request.getId());
        this.overVote(vote, DynamicConstant.CheckStatus.START);
        return true;
    }

    @Override
    public RoomVote verify(Long id) {
        Optional<RoomVote> roomVote = lambdaQuery()
                .eq(RoomVote::getId, id)
                .oneOpt();
        Assert.isTrue(roomVote.isPresent(), "当前投票不存在");
        return roomVote.get();
    }

    @Override
    public boolean giveVote(AppRoomVoteGiveRequest request, Long userId) {
        Room room = iRoomService.verify(request.getRoomId());
        RoomVote verify = verify(request.getId());
        Assert.isTrue(verify.getStatus().equals(DynamicConstant.CheckStatus.YES), "该场投票已结束/不存在");

        Gift gift = iGiftService.verify(request.getGiftId());

        Assert.isTrue(request.getTargetType().equals(DynamicConstant.TargetType.LEFT)
                ||
                request.getTargetType().equals(DynamicConstant.TargetType.RIGHT), "投票目标类型不存在");

        if (iPayService.giveGift(room.getId(), room.getRoomNumber(), gift, userId, Collections.singleton(room.getUserId()))) {
            //使用redis排行榜
            String key = RoomChatRoomKvConstant.ROOM_VOTE_LEFT + request.getTargetType();
            BigDecimal bigDecimal = CacheTemplate.insertRoomVote(key, verify.getId(), gift.getGiftPrice().doubleValue());

            BigDecimal leftGiftMoney = CacheTemplate.getZsetValue(RoomChatRoomKvConstant.ROOM_VOTE_LEFT + "0", verify.getId());
            BigDecimal rightGiftMoney = CacheTemplate.getZsetValue(RoomChatRoomKvConstant.ROOM_VOTE_LEFT + "1", verify.getId());

            AppRoomVoteResult build = AppRoomVoteResult.builder()
                    .leftGiftMoney(leftGiftMoney)
                    .rightGiftMoney(rightGiftMoney)
                    .build();

            //添加记录
            iRoomVoteRecordService.addRecord(room.getId(), request.getId(), gift.getId(), gift.getGiftImg(), gift.getGiftPrice(), "", userId, gift.getGiftName());

            iMessageService.setRoomChatRoomAttr(room.getGroupId(), room.getUserId().toString(), RoomChatRoomKvConstant.ROOM_VOTE_GIFT_INFO, JSONObject.toJSONString(build), 0, "", "");
        }
        return true;
    }

    @Override
    public void overVote(RoomVote roomVote, Integer status) {
        Room verify = iRoomService.verify(roomVote.getRoomId());
        /*倒计时结束*/
        if (status.equals(DynamicConstant.CheckStatus.FENG) && roomVote.getStatus().equals(DynamicConstant.CheckStatus.YES)) {
            Set<Long> collect = iRoomVoteRecordService.lambdaQuery()
                    .eq(RoomVoteRecord::getRoomVoteId, roomVote.getId())
                    .list().stream().map(RoomVoteRecord::getUserId).collect(Collectors.toSet());
            //第一个结束
            Calendar instance = Calendar.getInstance();
            instance.setTime(roomVote.getEndTime());
            instance.add(Calendar.SECOND, 60);
            roomVote.setStatus(status);
            roomVote.setEndTime(instance.getTime());
            roomVote.setJoinNumber(collect.size());

            BigDecimal left = CacheTemplate.getZsetValue(RoomChatRoomKvConstant.ROOM_VOTE_LEFT + "0", roomVote.getId());
            BigDecimal right = CacheTemplate.getZsetValue(RoomChatRoomKvConstant.ROOM_VOTE_LEFT + "1", roomVote.getId());
            roomVote.setLeftGiftMoney(left);
            roomVote.setRightGiftMoney(right);

            //发送redis过期事件
            CacheTemplate.setCacheExpire(RoomChatRoomKvConstant.ROOM_VOTE_END + roomVote.getId(), roomVote.getId(), 60L, TimeUnit.SECONDS);
        } else if (status.equals(DynamicConstant.CheckStatus.START)) {
            roomVote.setStatus(status);
            CacheTemplate.clear(RoomChatRoomKvConstant.ROOM_VOTE_END + roomVote.getId());
            CacheTemplate.clear(RoomChatRoomKvConstant.ROOM_VOTE + roomVote.getId());

            CacheTemplate.clear(RoomChatRoomKvConstant.ROOM_VOTE_LEFT + "0");
            CacheTemplate.clear(RoomChatRoomKvConstant.ROOM_VOTE_LEFT + "1");
            iMessageService.removeRoomKV(verify.getGroupId(), verify.getUserId().toString(), RoomChatRoomKvConstant.ROOM_VOTE_GIFT_INFO, "", "");
        }
        updateById(roomVote);

        AppRoomVoteInfoResult build = AppRoomVoteInfoResult
                .builder()
                .id(roomVote.getId())
                .otherGiftId(roomVote.getOtherGiftId())
                .roomId(roomVote.getRoomId())
                .status(roomVote.getStatus())
                .theseGiftId(roomVote.getTheseGiftId())
                .userId(roomVote.getUserId())
                .voteOther(roomVote.getVoteOther())
                .voteThese(roomVote.getVoteThese())
                .voteTime(roomVote.getVoteTime())
                .otherGiftImg(roomVote.getOtherGiftImg())
                .otherGiftPrice(roomVote.getOtherGiftPrice())
                .theseGiftImg(roomVote.getTheseGiftImg())
                .theseGiftPrice(roomVote.getTheseGiftPrice())
                .joinNumber(roomVote.getJoinNumber())
                .leftGiftMoney(roomVote.getLeftGiftMoney())
                .rightGiftMoney(roomVote.getRightGiftMoney())
                .build();
        iMessageService.setRoomChatRoomAttr(verify.getGroupId(), verify.getUserId().toString(), RoomChatRoomKvConstant.ROOM_RANK_INFO, JSONObject.toJSONString(build), 0, "", "");
    }

    @Override
    public Pages<RoomVote> listPage(AppRoomVoteSearchRequest request, Long userId) {
        Page<RoomVote> roomVotePage = PageUtils.initPage(request, RoomVote.class);
        Page<RoomVote> page = lambdaQuery()
                .eq(!CommonUtils.isNull(request.getRoomId()), RoomVote::getRoomId, request.getRoomId())
                .eq(RoomVote::getStatus, DynamicConstant.CheckStatus.START)
                .orderByDesc(RoomVote::getCreateTime).page(roomVotePage);
        for (RoomVote record : page.getRecords()) {
            record.setBeforeTime(DateUtils.format(record.getCreateTime()));
        }
        return PageUtils.pages(page);
    }

    @Override
    public AppRoomVoteInfoResult info(Long id) {
        RoomVote roomVote = verify(id);
        BigDecimal left = CacheTemplate.getZsetValue(RoomChatRoomKvConstant.ROOM_VOTE_LEFT + "0", roomVote);
        BigDecimal right = CacheTemplate.getZsetValue(RoomChatRoomKvConstant.ROOM_VOTE_LEFT + "1", roomVote);
        return AppRoomVoteInfoResult
                .builder()
                .id(roomVote.getId())
                .otherGiftId(roomVote.getOtherGiftId())
                .roomId(roomVote.getRoomId())
                .status(roomVote.getStatus())
                .theseGiftId(roomVote.getTheseGiftId())
                .userId(roomVote.getUserId())
                .voteOther(roomVote.getVoteOther())
                .voteThese(roomVote.getVoteThese())
                .voteTime(roomVote.getVoteTime())
                .residueTime(DateUtils.timeBySec(roomVote.getEndTime(), new Date()))
                .otherGiftImg(roomVote.getOtherGiftImg())
                .otherGiftPrice(roomVote.getOtherGiftPrice())
                .theseGiftImg(roomVote.getTheseGiftImg())
                .theseGiftPrice(roomVote.getTheseGiftPrice())
                .leftGiftMoney(left)
                .rightGiftMoney(right)
                .joinNumber(roomVote.getJoinNumber())
                .build();
    }

    @Override
    public List<Gift> cutGift(Integer number) {
        if (CommonUtils.isNull(number)) {
            number = 2;
        }
        return iGiftService.cutGift(number, CollectionUtils.emptySet());
    }
}
